
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.    
 */
using System;
using Velocity4Net.Runtime.Directives;
using Velocity4Net.Runtime.Parse.AST;
using Velocity4Net.Util.Introspection;
namespace Velocity4Net.Runtime.Logging
{
    /*
     * Licensed to the Apache Software Foundation (ASF) under one
     * or more contributor license agreements.  See the NOTICE file
     * distributed with this work for additional information
     * regarding copyright ownership.  The ASF licenses this file
     * to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance
     * with the License.  You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.    
     */

    /**
     * Convenient wrapper for LogChute functions. This implements
     * the RuntimeLogger methods (and then some).  It is hoped that
     * use of this will fully replace use of the RuntimeLogger.
     *
     * @author <a href="mailto:nbubna@apache.org">Nathan Bubna</a>
     * @version $Id: Log.java 724804 2008-12-09 18:17:08Z nbubna $
     * @since 1.5
     */
    public class Log
    {

        private LogChute chute;

        /**
         * Creates a new Log that wraps a HoldingLogChute.
         */
        public Log()
        {
            setLogChute(new HoldingLogChute());
        }

        /**
         * Creates a new Log that wraps the specified LogChute.
         * @param chute
         */
        public Log(LogChute chute)
        {
            setLogChute(chute);
        }

        /**
         * Updates the LogChute wrapped by this Log instance.
         * @param chute The new value for the log chute.
         */
        internal void setLogChute(LogChute chute)
        {
            if (chute == null)
            {
                throw new NullReferenceException("The LogChute cannot be set to null!");
            }
            this.chute = chute;
        }

        /**
         * Returns the LogChute wrapped by this Log instance.
         * @return The LogChute wrapped by this Log instance.
         */
        internal LogChute LogChute
        {
            get
            {
                return this.chute;
            }
        }

        internal void log(int level, Object message)
        {
            LogChute.log(level, message.ToString());
        }

        internal void log(int level, Object message, System.Exception t)
        {
            LogChute.log(level, message.ToString(), t);
        }

        /**
         * Returns true if trace level messages will be printed by the LogChute.
         * @return If trace level messages will be printed by the LogChute.
         */
        public bool isTraceEnabled()
        {
            return LogChute.isLevelEnabled(LogConstants.TRACE_ID);
        }

        /**
         * Log a trace message.
         * @param message
         */
        public void trace(Object message)
        {
            log(LogConstants.TRACE_ID, message);
        }

        /**
         * Log a trace message and accompanying Throwable.
         * @param message
         * @param t
         */
        public void trace(Object message, System.Exception t)
        {
            log(LogConstants.TRACE_ID, message, t);
        }

        /**
         * Returns true if debug level messages will be printed by the LogChute.
         * @return True if debug level messages will be printed by the LogChute.
         */
        public bool isDebugEnabled()
        {
            return LogChute.isLevelEnabled(LogConstants.DEBUG_ID);
        }

        /**
         * Log a debug message.
         * @param message
         */
        public void debug(Object message)
        {
            log(LogConstants.DEBUG_ID, message);
        }

        /**
         * Log a debug message and accompanying Throwable.
         * @param message
         * @param t
         */
        public void debug(Object message, System.Exception t)
        {
            log(LogConstants.DEBUG_ID, message, t);
        }

        /**
         * Returns true if info level messages will be printed by the LogChute.
         * @return True if info level messages will be printed by the LogChute.
         */
        public bool isInfoEnabled()
        {
            return LogChute.isLevelEnabled(LogConstants.INFO_ID);
        }

        /**
         * Log an info message.
         * @param message
         */
        public void info(Object message)
        {
            log(LogConstants.INFO_ID, message);
        }

        /**
         * Log an info message and accompanying Throwable.
         * @param message
         * @param t
         */
        public void info(Object message, System.Exception t)
        {
            log(LogConstants.INFO_ID, message, t);
        }

        /**
         * Returns true if warn level messages will be printed by the LogChute.
         * @return True if warn level messages will be printed by the LogChute.
         */
        public bool isWarnEnabled()
        {
            return LogChute.isLevelEnabled(LogConstants.WARN_ID);
        }

        /**
         * Log a warning message.
         * @param message
         */
        public void warn(Object message)
        {
            log(LogConstants.WARN_ID, message);
        }

        /**
         * Log a warning message and accompanying Throwable.
         * @param message
         * @param t
         */
        public void warn(Object message, System.Exception t)
        {
            log(LogConstants.WARN_ID, message, t);
        }

        /**
         * Returns true if error level messages will be printed by the LogChute.
         * @return True if error level messages will be printed by the LogChute.
         */
        public bool isErrorEnabled()
        {
            return LogChute.isLevelEnabled(LogConstants.ERROR_ID);
        }

        /**
         * Log an error message.
         * @param message
         */
        public void error(Object message)
        {
            log(LogConstants.ERROR_ID, message);
        }

        /**
         * Log an error message and accompanying Throwable.
         * @param message
         * @param t
         */
        public void error(Object message, System.Exception t)
        {
            log(LogConstants.ERROR_ID, message, t);
        }

        /**
         * Creates a string that formats the template filename with line number
         * and column of the given Directive. We use this routine to provide a cosistent format for displaying 
         * file errors.
         */
        public static String formatFileString(Directive directive)
        {
            return formatFileString(directive.TemplateName, directive.Line, directive.Column);
        }

        /**
         * Creates a string that formats the template filename with line number
         * and column of the given Node. We use this routine to provide a cosistent format for displaying 
         * file errors.
         */
        public static String formatFileString(INode node)
        {
            return formatFileString(node.TemplateName, node.Line, node.Column);
        }

        /**
         * Simply creates a string that formats the template filename with line number
         * and column. We use this routine to provide a cosistent format for displaying 
         * file errors.
         */
        public static String formatFileString(Info info)
        {
            return formatFileString(info.getTemplateName(), info.getLine(), info.getColumn());
        }

        /**
         * Simply creates a string that formats the template filename with line number
         * and column. We use this routine to provide a cosistent format for displaying 
         * file errors.
         * @param template File name of template, can be null
         * @param linenum Line number within the file
         * @param colnum Column number withing the file at linenum
         */
        public static String formatFileString(String template, int linenum, int colnum)
        {
            if (string.IsNullOrEmpty(template ))
            {
                template = "<unknown template>";
            }
            return template + "[line " + linenum + ", column " + colnum + "]";
        }
    }
}